package de.akabahn.ebd.comm;

/**
 * Connection observer class which monitors the state of the connection to a
 * remote server.
 * 
 * @author Peter Eimann
 * @since 0.2
 * @version 0.2
 * @see ObservableConnection
 */
public class ConnectionObserver implements Runnable {
	private ObservableConnection connectionToObserve;
	private boolean connected;
	private boolean stopped;

	/**
	 * Initialize this instance with the connection to observe.
	 * 
	 * @param connectionToObserve
	 *            The telnet connection to observe
	 */
	public ConnectionObserver(ObservableConnection connectionToObserve) {
		this.connectionToObserve = connectionToObserve;
	}

	/**
	 * Set the <code>isStopped</code> flag to true to prepare the current thread
	 * to stop
	 */
	public void prepareToStop() {
		stopped = true;
	}

	/**
	 * Checks the current connection status and compares it with last connection
	 * status. If they are different (meaning a connection has been established
	 * or closed), all registered observers are notified about this change,
	 * passing the new connection status. If the current connection status is
	 * false (meaning there's currently no connection), a reconnect is tried.
	 * The thread waits <code>Config.CONNECTION_OBSERVER_PERIOD_OK</code> or
	 * <code>Config.CONNECTION_OBSERVER_PERIOD_NOK</code> ms between each check,
	 * depending on the current connection status, and continues until the
	 * <code>isStopped</code> flag is set to true.
	 */
	public void run() {
		boolean nowConnected = false;
		Util.sleep(1000);

		while (!stopped) {
			nowConnected = connectionToObserve.isConnected();

			if (!nowConnected) {
				try {
					Util.sleep(500);
					connectionToObserve.reconnect();
					Util.sleep(500);
					nowConnected = connectionToObserve.isConnected();
				} catch (Exception e) {
				}
			}

			if (connected != nowConnected) {
				connected = nowConnected;
				connectionToObserve.setChanged();
				connectionToObserve.notifyObservers(Boolean.valueOf(nowConnected));
			}

			Util.sleep(nowConnected ? 15000 : 5000);
		}
	}
}
